﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Infrastructure.CrossCutting.Caching
{
    public class MemcachedCache : IDistributedCache
    {
        #region Static

        // MemcachedClient need to be singleton
        private static Enyim.Caching.IMemcachedClient MemcachedInstance
        {
            get
            {
                if (_MemcachedInstance == null)
                {
                    lock (_locker)
                    {
                        if (_MemcachedInstance == null)
                        {
                            _MemcachedInstance = new Enyim.Caching.MemcachedClient();
                        }
                    }
                }
                return _MemcachedInstance;
            }
        }
        private static Enyim.Caching.IMemcachedClient _MemcachedInstance;

        private static readonly object _locker = new object();

        public static MemcachedCache Create()
        {
            return new MemcachedCache(MemcachedInstance);
        }

        #endregion Static

        #region Fields

        private Enyim.Caching.IMemcachedClient _Cache;

        #endregion Fields

        #region Constructor

        public MemcachedCache(Enyim.Caching.IMemcachedClient cache)
        {
            _Cache = cache;
        }

        #endregion Constructor

        #region ICache Members

        public object Get(CacheKey cacheKey)
        {
            var cache = _Cache;
            string key = cacheKey.GetCacheKey();
            return cache.Get(key);
        }

        public void Set(CacheItemConfig cacheItemConfig, object value)
        {
            var cache = _Cache;

            string key = cacheItemConfig.CacheKey.GetCacheKey();
            TimeSpan expirationTime = cacheItemConfig.ExpirationTime;

            if (!cache.Store(
                Enyim.Caching.Memcached.StoreMode.Set,
                key,
                value,
                expirationTime))
            {
              throw (new InvalidOperationException("Cannot set value to memcached server. Check the configuration."));
            }
        }

        public bool Remove(CacheKey cacheKey)
        {
            string key = cacheKey.GetCacheKey();
            return _Cache.Remove(key);
        }

        public void Clear()
        {
            _Cache.FlushAll();
        }

        #endregion ICache Members

    }
}
